/**
 * 拥有Remote list功能的表格.
 *
 * @author liuhz
 */
CQCIS.grid.ListGrid = Ext.extend(Ext.grid.GridPanel, {
    /**
     * @cfg {dwr} DWR call DWR方法
     *
     * <pre>
     * ---------------------------------
     * call     list call              DWR list方法
     * params   params                 参数
     * </pre>
     * @cfg {id} recordmeta 与数据库主键对应的属性设置
     * @cfg {boolean} initload default:false 是否在初始化时加载数据
     * @cfg {array} selecteds 选中行记录数据
     * @cfg {metas} Records Metas 字段显示属性设置
     *
     * <pre>
     * ------recordHeaders--------------
     * id       ID
     * field    字段
     * desc     描述
     * type     字段类型
     * mapping  映射
     * renderer 渲染方法
     * ------fieldMetas-------------
     * sort     [true, false],
     * hidden   [true, false],
     * width    width (xx)
     * filter   [true, false]
     * </pre>
     */
    stateful: false,
    stripeRows: true,
    loadMask: {
        msg: '读取中，请稍候......'
    },
    border: false,
    ddText: '{0} 条选中记录',
    viewConfig: {
        autoFill: true
    },
    autoScroll: true,
    bodyStyle: 'width:100%',
    isGroupHeader: false,
    
    // overwrite
    initComponent: function(){
        if (!this.el && !this.renderTo) {
            var obj = Ext.getBody().createChild({
                tag: 'div',
                name: 'mainContent',
                style: this.width ? 'height:100%;' : 'width:100%;height:100%;'
            });
            this.renderTo = obj;
        }
        Ext.apply(this.viewConfig, {
            handleHdOver: function(e, t){
                var hd = this.findHeaderCell(t);
                if (hd && !this.headersDisabled) {
                    this.activeHd = hd;
                    this.activeHdIndex = this.getCellIndex(hd);
                    var fly = this.fly(hd);
                    this.activeHdRegion = fly.getRegion();
                    if (!this.cm.isFixed(this.activeHdIndex)) {
                        fly.addClass("x-grid3-hd-over");
                        this.activeHdBtn = fly.child('.x-grid3-hd-btn');
                        if (this.activeHdBtn) {
                            this.activeHdBtn.dom.style.height = (hd.firstChild.offsetHeight - 1) + 'px';
                        }
                    }
                }
            }
        });
        this.initMetas();
        this.initCm();
        this.initDs();
        
        this.initTbar();
        this.initBbar();
        
        if (this.isGroupHeader === true) {
            this.plugins = this.plugins || [];
            this.plugins.push(new Ext.ux.plugins.GroupHeaderGrid());
        }
        
        CQCIS.grid.ListGrid.superclass.initComponent.call(this);
        
        if (this.initConfig) {
            delete this.initConfig;
        }
        
        this.addEvents({
            /**
             * @event on beforeload
             */
            'loadcheck': true,
            
            /**
             * @event on added
             */
            'added': true,
            
            /**
             * @event on delete
             */
            'beforedelete': true,
            'deleteafter': true
        });
    },
    // private
    initMetas: function(){
        if (!this.metas) {
            return;
        }
        
        var columnHeaders = [];
        var recordHeaders = [];
        var filterFields = [];
        
        if (this.firstColumn == 'checkbox') {
            columnHeaders[0] = new Ext.grid.CheckboxSelectionModel(this.disableSelection ? {
                selectRow: Ext.emptyFn
            } : {
                selectRow: function(index, keepExisting, preventViewNotify){
                    if (this.locked || (index < 0 || index >= this.grid.store.getCount())) {
                        return;
                    }
                    var r = this.grid.store.getAt(index);
                    if (r && this.fireEvent("beforerowselect", this, index, keepExisting, r) !== false) {
                        this.selections.add(r);
                        this.last = this.lastActive = index;
                        if (!preventViewNotify) {
                            this.grid.getView().onRowSelect(index);
                        }
                        this.fireEvent("rowselect", this, index, r);
                        this.fireEvent("selectionchange", this);
                    }
                }
                
            });
        } else if (this.firstColumn == 'number') {
            columnHeaders[0] = new Ext.grid.RowNumberer(this.disableSelection ? {
                selectRow: Ext.emptyFn
            } : null);
        } else if (this.firstColumn && typeof this.firstColumn == 'object') {
            columnHeaders[0] = this.firstColumn;
        } else if (this.firstColumn == 'radio') {
            var param = {
                singleSelect: true,
                header: ''
            };
            if (this.disableSelection) {
                param.selectRow = Ext.emptyFn;
            }
            columnHeaders[0] = new CQCIS.grid.RadioSelectionModel(param);
        } else if (this.firstColumn == 'expander') {
            var obj = new CQCIS.grid.RowExpander({
                tpl: this.tpl
            });
            columnHeaders[0] = obj;
            if (!this.enableDragDrop) {
                if (this.plugins && this.plugins instanceof Array) {
                    this.plugins.push(obj);
                    //this.plugins.push(new Ext.ux.grid.DragSelector());
                } else if (this.plugins) {
                    //this.plugins = [this.plugins, obj, new Ext.ux.grid.DragSelector()];
                } else {
                    //this.plugins = [obj, new Ext.ux.grid.DragSelector()];
                }
            } else {
                if (this.plugins && this.plugins instanceof Array) {
                    this.plugins.push(obj);
                } else if (this.plugins) {
                    this.plugins = [this.plugins, obj];
                } else {
                    this.plugins = obj;
                }
            }
        }
        
        if (columnHeaders[0] instanceof Ext.grid.AbstractSelectionModel) {
            this.sm = columnHeaders[0];
        }
        
        for (var i = 0; i < this.metas.length; i++) {
            var meta = this.metas[i], f = {}, r = {};
            /* columnHeader */
            f.header = meta.desc;
            f.dataIndex = meta.field;
            if (meta.id) {
                f.id = meta.id;
            }
            if (meta.width) {
                f.width = meta.width;
            }
            if (meta.hidden) {
                f.hidden = meta.hidden;
            }
            f.sortable = meta.sort ? meta.sort : false;
            if (meta.renderer) {
                f.renderer = meta.renderer;
            } else if (meta.type == 'date') {
                f.renderer = Ext.util.Format.dateRenderer('Y-m-d');
            } else if (meta.type == 'time') {
                f.renderer = Ext.util.Format.dateRenderer('Y-m-d H:i:s');
            }
            
            columnHeaders[columnHeaders.length] = f;
            
            /* recordHeader */
            r.name = meta.field;
            r.type = meta.type && meta.type != 'time' ? meta.type : 'string';
            if (meta.mapping) {
                r.mapping = meta.mapping;
            }
            recordHeaders[recordHeaders.length] = r;
            
            /* filterField */
            if (meta.filter) {
                filterFields[filterFields.length] = {
                    text: meta.desc,
                    value: meta.field
                };
            }
        }
        
        this.columnHeaders = columnHeaders;
        this.recordHeaders = recordHeaders;
        
        if (filterFields.length) {
            this.filterFields = filterFields;
        }
        delete this.metas;
    },
    // private
    initTbar: function(){
        if (this.tbar === true || this.tbar == 'true' || (!this.tbar && this.filterFields)) {
            this.tbar = ['-'];
        }
    },
    // private
    initBbar: function(){
        if (this.tbar === true || this.bbar == 'true') {
            this.bbar = ['-'];
        }
    },
    // private
    initCm: function(){
        if (!this.cm && this.columnHeaders) {
            this.cm = new Ext.grid.ColumnModel({
                columns: this.columnHeaders,
                rows: this.isGroupHeader === true ? this.rows : undefined
            });
            if (this.sortable) {
                this.cm.defaultSortable = this.sortable;
            }
            delete this.columnHeaders;
        }
    },
    // private
    initDs: function(){
        if (!this.ds && this.recordHeaders) {
            this.ds = new CQCIS.data.DWRStore({
                proxy: new CQCIS.data.DWRProxy({
                    call: this.dwr.call,
                    params: this.dwr.params,
                    ownerCt: this
                }),
                reader: new CQCIS.data.DWRReader(this.recordHeaders, this.recordmeta),
                remoteSort: true
            });
            // this.store.proxy.ownerCt = this;
            delete this.recordHeaders;
        }
    },
    // overwrite
    onRender: function(ct, position){
        CQCIS.grid.ListGrid.superclass.onRender.call(this, ct, position);
        
        if (this.filterFields) {
            this.addFieldFilter(this.filterFields);
        }
        
        Ext.applyIf(this.store.baseParams, {
            params: this.params,
            filter: this.filter,
            like: this.like
        });
        
        this.store.on('beforeload', function(){
            if (this.fireEvent('loadcheck', this) !== false) {
                if (this.params || this.filter || this.like) {
                    Ext.applyIf(this.store.baseParams, {
                        params: this.params,
                        filter: this.filter,
                        like: this.like
                    });
                }
                return true;
            } else {
                this.store.removeAll();
                this.loadMask.hide();
                return false;
            }
        }, this);
        
        this.store.on('load', function(){
            if (this.selecteds && this.recordmeta.id && this.selModel) {
                var header = Ext.DomQuery.select('.x-grid3-hd-checker', this.el.dom.parentNode);
                var records = [];
                if (this.selecteds.length > 0) {
                    for (var i = 0; i < this.selecteds.length; i++) {
                        records[i] = this.store.getById(this.selecteds[i][this.recordmeta.id]);
                    }
                    if (header) {
                        Ext.get(header[0]).addClass('x-grid3-hd-checker-on');
                    }
                } else if (header) {
                    Ext.get(header[0]).removeClass('x-grid3-hd-checker-on');
                }
                this.getSelectionModel().selectRecords(records);
                
                delete this.selecteds;
            }
        }, this);
        
        if (this.initload) {
            this.store.load();
        }
        
        this.on('rowcontextmenu', function(grid, index, e){
            e.stopEvent();
            this.getSelectionModel().clearSelections();
            this.getSelectionModel().selectRow(index);
        }, this);
        
        if (Ext.isIE) {
            if (!this.hasListener('cellclick')) {
                this.on('cellclick', function(o, rowIndex, columnIndex, e){
                    var obj = e.target;
                    if (obj.innerHTML == '&nbsp;') {
                        return;
                    }
                    var ran = document.body.createTextRange();
                    ran.moveToElementText(obj);
                    ran.collapse(true);
                    ran.moveStart('character', 0);
                    ran.moveEnd('character', obj.innerText.length);
                    ran.select();
                });
            }
            
            if (!this.hasListener('cellcontextmenu')) {
                this.on('cellcontextmenu', function(o, rowIndex, columnIndex, e){
                    var obj = e.target;
                    if (obj.innerHTML == '&nbsp;') {
                        return;
                    }
                    var ran = document.body.createTextRange();
                    ran.moveToElementText(obj);
                    ran.collapse(true);
                    ran.moveStart('character', 0);
                    ran.moveEnd('character', obj.innerText.length);
                    ran.select();
                });
            }
        } else {
            this.setHeight(top.center.getSize().height - 29);
        }
        
        if (this.el.parent().dom.name && this.el.parent().dom.name == 'mainContent') {
            this.on('render', function(){
                this.syncSize();
            }, this, {
                single: true
            });
            
            this.on('added', function(o, ct){
                if (ct.rendered) {
                    if (ct.initialConfig.layout === 'border') {
                        o.setWidth((ct.body.getWidth() - 10) / ct.initialConfig.items.length);
                    } else {
                        o.setWidth(ct.body.getWidth() - 10);
                    }
                    o.setHeight(ct.body.getHeight() - 10);
                } else {
                    ct.on('render', function(){
                        o.setWidth(ct.body.getWidth() - 10);
                        o.setHeight(ct.body.getHeight() - 10);
                    }, ct, {
                        single: true
                    });
                }
            }, this, {
                single: true
            });
        }
    },
    syncSize: function(){
        if (top.center) {
            this.setSize({
                width: top.center.getSize().width,
                height: top.center.getSize().height - 29
            });
        }
    },
    // 增加过滤框默认在TOP
    addFieldFilter: function(meta, text, value, bottom){
        var filterItems = [];
        text = text ? text : 'text';
        value = value ? value : 'value';
        for (var i = 0; i < meta.length; i++) {
            var item = new Ext.menu.CheckItem({
                text: meta[i][text],
                value: meta[i][value],
                checked: i === 0 ? true : false,
                group: "filter",
                checkHandler: this.onFilterCheck.createDelegate(this)
            });
            filterItems[filterItems.length] = item;
        }
        this.fField = meta[0][value];
        
        var tbar = bottom ? this.getBottomToolbar() : this.getTopToolbar();
        this.fBtn = new Ext.Toolbar.Button({
            icon: CQCIS.jsPath + 'icon/icon-search.png',
            cls: 'x-btn-text-icon',
            text: meta[0][text],
            tooltip: '请选择搜索的字段',
            minWidth: 80,
            menu: new Ext.menu.Menu({
                id: 'filteMenu',
                items: filterItems
            })
        });
        
        tbar.add(this.fBtn);
        this.fTxt = Ext.get(tbar.addField(new Ext.form.TextField({
            emptyText: '请输入字段值'
        })).getEl());
        
        this.fTxt.on('keypress', function(e){
            if (e.getKey() == e.ENTER && this.fTxt.getValue().length > 0) {
                this.filter[this.fField] = this.fTxt.getValue();
                this.reload();
            }
        }, this);
        
        this.fTxt.on('keyup', function(e){
            if (e.getKey() == e.BACKSPACE && this.fTxt.getValue().length === 0) {
                delete this.filter[this.fField];
                this.reload();
            }
        }, this);
    },
    
    /** private */
    onFilterCheck: function(item, checked){
        if (checked) {
            delete this.filter[this.fField];
            this.fBtn.setText(item.text + ':');
            this.fField = item.value;
        }
    },
    
    /**
     * 刷新Grid,加载数据
     */
    reload: function(arg){
        this.store.reload(arg);
    },
    
    /**
     * 刷新当前页
     */
    refresh: function(){
        this.store.reload();
    },
    /**
     * 清除表格数据
     */
    clear: function(){
        this.store.removeAll();
    },
    
    /**
     * 在TOP工具栏增加组件
     */
    addTop: function(){
        if (this.rendered) {
            var a = arguments, l = a.length;
            var tbar = this.getTopToolbar();
            for (var i = 0; i < l; i++) {
                if (a[i] instanceof Array) {
                    for (var j = 0; j < a[i].length; j++) {
                        tbar.add(a[i][j]);
                    }
                } else {
                    tbar.add(a[i]);
                }
            }
        } else {
            this.addTop.defer(100, this, [arguments]);
        }
    },
    
    /**
     * 在BOTTOM工具栏增加组件
     */
    addBottom: function(){
        if (this.rendered) {
            var a = arguments, l = a.length;
            var bbar = this.getBottomToolbar();
            for (var i = 0; i < l; i++) {
                if (a[i] instanceof Array) {
                    for (var j = 0; j < a[i].length; j++) {
                        bbar.add(a[i][j]);
                    }
                } else {
                    bbar.add(a[i]);
                }
            }
        } else {
            this.addTop.defer(100, this, [arguments]);
        }
    },
    
    /**
     * 返回选定行数据
     */
    getSelectedRow: function(){
        return this.getSelectionModel().getSelected() ? this.getSelectionModel().getSelected().data : null;
    }
});
Ext.reg('lgrid', CQCIS.grid.ListGrid);
